package controll

import (
	"encoding/json"
	"fmt"
	"haodayizhi/global"
	"haodayizhi/model"
	mtype "haodayizhi/types"
	util "haodayizhi/utils"
	"net/http"
	"path/filepath"
	"strconv"
	"time"

	"github.com/gin-gonic/gin"
)

// 获取产品信息
func GetProductInfo(c *gin.Context) {
	response := mtype.ResponseType{
		Code:    200,
		Message: "success",
	}
	//  获取ID
	id := c.Param("p_id")
	// 转化id为int
	idInt, err := strconv.Atoi(id)
	if err != nil || idInt <= 0 {
		util.CommonErrorHandler(c, "id参数错误", http.StatusBadRequest, response, err)
		return
	}
	// 获取产品信息
	productModel := model.Product{}
	productRes, err := productModel.GetProductByID(int64(idInt))
	if err != nil {
		util.CommonErrorHandler(c, "获取产品信息失败", http.StatusInternalServerError, response, err)
		return
	}
	response.Result = productRes
	c.JSON(http.StatusOK, response)
}

// 获取产品列表
func GetProductList(c *gin.Context) {
	response := mtype.ResponseType{
		Code:    200,
		Message: "success",
	}
	listParams := mtype.ProductListParam{}
	// 获取参数
	if err := c.ShouldBind(&listParams); err != nil {
		util.CommonErrorHandler(c, "参数错误", http.StatusBadRequest, response, err)
		return
	}

	// 获取产品列表
	productsRes, total, err := model.GetProductList(listParams.Page, listParams.Limit)
	if err != nil {
		util.CommonErrorHandler(c, "获取产品信息失败", http.StatusInternalServerError, response, err)
		return
	}
	response.Result = mtype.ProductList{
		Total: total,
		List:  productsRes,
	}

	response.Result = productsRes
	c.JSON(http.StatusOK, response)
}

// 更新商品信息
func UpdateProductInfo(c *gin.Context) {
	product := &model.Product{}
	response := mtype.ResponseType{
		Code:    http.StatusOK,
		Message: "修改成功",
	}
	// 获取参数
	id := c.Query("p_id")
	if id == "" {
		util.CommonErrorHandler(c, "参数错误", http.StatusBadRequest, response, nil)
		return
	}
	// 转化id为int
	idInt, err := strconv.Atoi(id)
	if err != nil || idInt <= 0 {
		util.CommonErrorHandler(c, "id参数错误", http.StatusBadRequest, response, err)
		return
	}

	// 获取用户信息
	result, err := product.GetProductByID(int64(idInt))
	if err != nil {
		util.CommonErrorHandler(c, "Failed to get product info", http.StatusInternalServerError, nil, err)
		return
	}

	// 获取用户的请求信息
	err = c.ShouldBindJSON(&product)
	if err != nil {
		util.CommonErrorHandler(c, "Failed to get product info", http.StatusInternalServerError, nil, err)
		return
	}

	now := time.Now()
	// 修改用户信息
	result.Name = product.Name
	result.Detail = product.Detail
	result.Effects = product.Effects
	// 上下架需要权限
	result.IsRemoved = product.IsRemoved
	result.Price = product.Price
	// 修改折扣率需要权限
	result.DiscountRate = product.DiscountRate
	// 如果产品下架了，则修改下架时间
	if product.IsRemoved == 1 {
		result.RemovedAt = now
	} else {
		// 如果产品上架了，则修改上架时间
		if product.IsRemoved == 0 && result.IsRemoved == 1 {
			result.CreatedAt = now
		}
	}
	err = product.UpdateProduct()
	if err != nil {
		util.CommonErrorHandler(c, "Failed to get product info", http.StatusInternalServerError, nil, err)
		return
	}
	response.Result = result
	c.JSON(http.StatusOK, response)
}

// 上传图片
func UploadProductPic(c *gin.Context) {
	idStr := c.Query("id")
	id, err := strconv.Atoi(idStr)
	if err != nil || id <= 0 {
		util.CommonErrorHandler(c, "Invalid product ID", http.StatusBadRequest, nil, err)
		return
	}

	prod := &model.Product{}
	product, err := prod.GetProductByID(int64(id))
	if err != nil {
		util.CommonErrorHandler(c, "Error retrieving product info", http.StatusBadRequest, nil, err)
		return
	}

	// 支持上传多个文件
	form, err := c.MultipartForm()
	if err != nil {
		util.CommonErrorHandler(c, "Error retrieving form data", http.StatusBadRequest, nil, err)
		return
	}

	files := form.File["files"]
	if len(files) == 0 {
		util.CommonErrorHandler(c, "No files uploaded", http.StatusBadRequest, nil, nil)
		return
	}

	// 获取根目录
	rootDir, err := util.GetRootDir()
	if err != nil {
		util.CommonErrorHandler(c, "Error getting root directory", http.StatusInternalServerError, nil, err)
		return
	}

	// 构建文件存储路径
	productDir := filepath.Join(rootDir, "asset/static/product", fmt.Sprintf("%d_%s", product.ID, product.Name))

	// 确保目录存在
	if err := EnsureDirExists(productDir); err != nil {
		util.CommonErrorHandler(c, "Error creating directory", http.StatusInternalServerError, nil, err)
		return
	}

	var imagePaths []string
	for _, file := range files {
		// 创建唯一的文件名
		uniqueFilename := fmt.Sprintf("%d_%s_%s", product.ID, product.Name, file.Filename)
		filePath := filepath.Join(productDir, uniqueFilename)

		if err := c.SaveUploadedFile(file, filePath); err != nil {
			util.CommonErrorHandler(c, "Error saving file", http.StatusInternalServerError, nil, err)
			return
		}

		// 生成图片 URL
		imageUrl := fmt.Sprintf("%s/asset/static/product/%d_%s/%s", GetDomain(), product.ID, product.Name, uniqueFilename)
		imagePaths = append(imagePaths, imageUrl)
	}

	// Parse existing image paths JSON
	var existingImagePaths []string
	if product.ImagePaths != "" {
		if err := json.Unmarshal([]byte(product.ImagePaths), &existingImagePaths); err != nil {
			util.CommonErrorHandler(c, "Error parsing existing image paths", http.StatusInternalServerError, nil, err)
			return
		}
	}
	// Add new image URLs to the list
	existingImagePaths = append(existingImagePaths, imagePaths...)

	// Encode updated image paths list back to JSON
	updatedImagePaths, err := json.Marshal(existingImagePaths)
	if err != nil {
		util.CommonErrorHandler(c, "Error encoding updated image paths", http.StatusInternalServerError, nil, err)
		return
	}

	product.ImagePaths = string(updatedImagePaths)
	// 更新产品的图片路径
	if err := prod.UpdateProduct(); err != nil {
		util.CommonErrorHandler(c, "Error updating product image paths", http.StatusInternalServerError, nil, err)
		return
	}

	c.JSON(http.StatusOK, mtype.ResponseType{
		Code:    http.StatusOK,
		Message: "Images uploaded successfully",
		Result:  map[string]interface{}{"imageUrls": imagePaths},
	})
}

// 产品购买记录
func ProductBuyRecord(c *gin.Context) {
	response := mtype.ResponseType{
		Code:    http.StatusOK,
		Message: "获取成功",
	}
	listParams := mtype.ProductBuyRecordParam{
		Page:  1,
		Limit: 5,
	}
	//
	if err := c.ShouldBind(&listParams); err != nil {
		util.CommonErrorHandler(c, "Error retrieving form data", http.StatusBadRequest, nil, err)
		return
	}
	// 如果 id 存在 就访问id的购买记录
	if listParams.Uid > 0 {
		// 获取用户 ID
		userBuyList, total, err := model.GetPurchaseRecordByUserID(listParams.Page, listParams.Limit, int64(listParams.Uid))
		if err != nil {
			util.CommonErrorHandler(c, "Error getting user id from session", http.StatusUnauthorized, nil, err)
			return
		}
		response.Result = mtype.ProductList{
			List:  userBuyList,
			Total: total,
		}
		c.JSON(http.StatusOK, response)
		return
	}

	// 否者就从token中获取用户id
	tokenConfig := mtype.TokenConfig{}
	headInfo, exists := c.Get(global.LOG_USER)
	headInfoByte, err := json.Marshal(headInfo)
	if err != nil {
		util.LogMessage(util.LogTypeError, fmt.Sprintf("Failed to get user info: %v", err))
		response.Code = http.StatusInternalServerError
		response.Message = "Failed to get user info"
		c.JSON(http.StatusInternalServerError, response)
		return
	}
	err = json.Unmarshal(headInfoByte, &tokenConfig)
	if err != nil {
		util.LogMessage(util.LogTypeError, fmt.Sprintf("Failed to get user info: %v", err))
		response.Code = http.StatusInternalServerError
		response.Message = "Failed to get user info"
		c.JSON(http.StatusInternalServerError, response)
		return
	}
	if !exists {
		util.LogMessage(util.LogTypeError, fmt.Sprintf("Failed to get user info: %v", exists))
		response.Code = http.StatusInternalServerError
		response.Message = "Failed to get user info"
		c.JSON(http.StatusInternalServerError, response)
		return
	}

	// 查询购买记录
	buyRecords, total, err := model.GetPurchaseRecordByUserID(listParams.Page, listParams.Limit, tokenConfig.UserID)
	if err != nil {
		util.CommonErrorHandler(c, "Error retrieving buy records", http.StatusInternalServerError, nil, err)
		return
	}
	response.Result = mtype.ProductList{
		List:  buyRecords,
		Total: total,
	}
	c.JSON(http.StatusOK, response)
}
